/*
 *  scoreBoard - Utils.h
 *  Copyright 2011 W. Reckman. All rights reserved.
 */
#ifndef UTILS_H
#define UTILS_H

#include <string>
#include <vector>
#include "ofTypes.h"
#include "ofTrueTypeFont.h"

enum DIRECTION {
	D_RIGHT, D_DOWN, D_LEFT, D_UP, D_STOP
};

enum BALANCE_KIND {
	BK_CULTURE, BK_INDUSTRY, BK_NEUTRAL
};

enum GAME_STATE {
	GS_IDLE, GS_PRECOUNT, GS_PLAYING, GS_END_SEQUENCE, GS_END, GS_INVALID
};

enum FEEDBACK_IMAGES {
	FB_BALANCE, FB_GOOD, FB_MODERATE, FB_BAD
};

enum PLAYER_COLOR_BRIGHTNESS {
	PCB_DIMMED, PCB_NORMAL
};

const std::string& dirText( DIRECTION dir_ );
const std::string& balanceText( BALANCE_KIND bk_ );

const std::string& gameStateText( GAME_STATE gs_ );
const GAME_STATE lookupGameStateText( const string& text_ );


void drawTtfStringCentered( ofTrueTypeFont& font, const std::string& s, int x, int y );

bool parseBool( const std::string& value );
std::vector<std::string>* tokenize( const std::string& text, char splitChar );
float pointDist( const ofPoint& p1, const ofPoint& p2 );
float pointManhattanDist( const ofPoint& p1, const ofPoint& p2 );

//This function determines the 'quadrant' to which the vector p1->p2 points.
//right=-45/45deg, top=45/135deg, left=135/225deg, down=225/315deg
DIRECTION getVectorOrientation( const ofPoint& p1, const ofPoint& p2 );
bool circleIntersectsWith( const ofPoint& cPos_, float cRad_, const ofRectangle& rect_ );

const string& getOscGameStateName( GAME_STATE state_ );


template<class T = int>
class GridPoint {
public:
	T x, y;
	int colIdx, rowIdx;
	
	
	GridPoint()
	: x( -1 ), y( -1 ), colIdx( -1 ), rowIdx( -1 )
	{}
	
	GridPoint( T x_, T y_ )
	: x( x_ ), y( y_ ), colIdx( -1 ), rowIdx( -1 )
	{}
	
	GridPoint( T x_, T y_, int colIdx_, int rowIdx_ )
	: x( x_ ), y( y_ ), colIdx( colIdx_ ), rowIdx( rowIdx_ )
	{}
	
	GridPoint( const GridPoint<T>& other_ )
	: x( other_.x ), y( other_.y ), colIdx( other_.colIdx ), rowIdx( other_.rowIdx )
	{}
	
	GridPoint( const ofPoint& pos_ )
	: x( pos_.x ), y( pos_.y ), colIdx( -1 ), rowIdx( -1 )
	{}
	
	
	T distanceTo( const GridPoint<T>& other_ ) const {
		T dx = other_.x - x, dy = other_.y - y;
		return sqrtl( dx * dx + dy *dy );
	}
	
	T distanceTo( const ofPoint& other_ ) const {
		T dx = other_.x - x, dy = other_.y - y;
		return sqrtl( dx * dx + dy *dy );
	}
	
	T manhattanDistanceTo( const GridPoint<T>& other_ ) const {
		return fabsl( other_.x - x ) + fabsl( other_.y - y );
	}
	
	T manhattanDistanceTo( const ofPoint& other_ ) const {
		return fabsl( other_.x - x ) + fabsl( other_.y - y );
	}
	
	bool operator==( const GridPoint& other_ ) const {
		return x == other_.x && y == other_.y && colIdx == other_.colIdx && rowIdx == other_.rowIdx;
	}
};

#endif /* ! UTILS_H */
